#include "TexturedEntity.h"
#include "Animation.h"

Animation::Animation(TexturedEntity* entity)
: m_entity(entity), m_currentFrame(0), m_elapsedTime(0.0f), m_animationFinished(false), m_loop(false),
m_verticalFlip(false)
{
    m_positionInTexture.clear();
    m_dimension.clear();
    m_frameTimeout.clear();
}

Animation::~Animation(void)
{
}

void Animation::addFrame(const AnimationFrame& frame)
{
    m_positionInTexture.push_back(frame.posInTexture);
    m_dimension.push_back(frame.size);
    m_frameTimeout.push_back(frame.duration);
}

void Animation::update(float dT)
{
    m_elapsedTime += dT;
    float totalTime = 0.0f;
    for (int i=0; i<=m_currentFrame; i++)
    {
        // TODO : check for existance
        totalTime += m_frameTimeout.at(i);
    }

    if (m_elapsedTime > totalTime)
    {
        // Change animation frame if possible
        if (m_frameTimeout.size() == (m_currentFrame + 1))
        {
            // Animation has finished
            if (m_loop)
            {
                m_currentFrame = 0;
                m_elapsedTime = 0.0f;
            }
            else
            {
                m_animationFinished = true;
            }
        }
        else
        {
            m_currentFrame++;
        }
    }  // if (m_elapsedTime > totalTime)

    // Execute specific animation updates
    onUpdate(dT);
}

std::vector<float> Animation::getTexCoord(const Dimension& texSize) const
{
    std::vector<float> coords;
    if (m_verticalFlip)
    {
        coords.push_back((m_positionInTexture.at(m_currentFrame).x + m_dimension.at(m_currentFrame).width) / texSize.width);
        coords.push_back(m_positionInTexture.at(m_currentFrame).y / texSize.height);
        coords.push_back(m_positionInTexture.at(m_currentFrame).x / texSize.width);
        coords.push_back(m_positionInTexture.at(m_currentFrame).y / texSize.height);
        coords.push_back(m_positionInTexture.at(m_currentFrame).x / texSize.width);
        coords.push_back((m_positionInTexture.at(m_currentFrame).y + m_dimension.at(m_currentFrame).height) / texSize.height);
        coords.push_back((m_positionInTexture.at(m_currentFrame).x + m_dimension.at(m_currentFrame).width) / texSize.width);
        coords.push_back((m_positionInTexture.at(m_currentFrame).y + m_dimension.at(m_currentFrame).height) / texSize.height);
    }
    else
    {
        coords.push_back(m_positionInTexture.at(m_currentFrame).x / texSize.width);
        coords.push_back(m_positionInTexture.at(m_currentFrame).y / texSize.height);
        coords.push_back((m_positionInTexture.at(m_currentFrame).x + m_dimension.at(m_currentFrame).width) / texSize.width);
        coords.push_back(m_positionInTexture.at(m_currentFrame).y / texSize.height);
        coords.push_back((m_positionInTexture.at(m_currentFrame).x + m_dimension.at(m_currentFrame).width) / texSize.width);
        coords.push_back((m_positionInTexture.at(m_currentFrame).y + m_dimension.at(m_currentFrame).height) / texSize.height);
        coords.push_back(m_positionInTexture.at(m_currentFrame).x / texSize.width);
        coords.push_back((m_positionInTexture.at(m_currentFrame).y + m_dimension.at(m_currentFrame).height) / texSize.height);
    }

    return coords;
}

bool Animation::hasAnimationFinished(void) const
{
    return m_animationFinished;
}
